/*
 * Project it.battlehorse.rcp.tools
 * Created on Nov 18, 2005
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * A copy of the LGPL is available also at
 * http://www.gnu.org/copyleft/lesser.html
 * 
 */
package it.battlehorse.rcp.tools.actors.impl;

import it.battlehorse.rcp.tools.actors.ActorDescriptor;
import it.battlehorse.rcp.tools.actors.IActor;
import it.battlehorse.rcp.tools.actors.IActorConstants;
import it.battlehorse.rcp.tools.actors.IActorRegistry;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.Platform;

/**
 * The default implementation for the {@link IActorRegistry} interface. This implementation adopts
 * the singleton pattern so that only a single instance of the class is available to the
 * platform.
 * 
 * @author battlehorse
 * @since Nov 18, 2005
 */
public class ActorRegistry implements IActorConstants, IActorRegistry {

	/**
	 * Contains the shared instance of the registry
	 */
	private static ActorRegistry instance;
	
	/**
	 * The list of Actors known to the platoform
	 */
	private List<ActorDescriptor> knownActorsConfiguration;
		
	/**
	 * Returns the shared instance of the class. This method should not be invoked
	 * directly : the registry should be accessed using the service locator framework
	 * 
	 * @return the shared actor registry instance
	 */
	public static synchronized ActorRegistry getInstance() {
		if (instance == null)
			instance =  new ActorRegistry();
		
		return instance;
	}
		 
	private ActorRegistry() {				
		
		//
		// Extension registry lookup to find actors contributions
		//
		knownActorsConfiguration = new ArrayList<ActorDescriptor>();
		
		IExtension[] extensions = Platform.getExtensionRegistry().getExtensionPoint(ACTOR_EXTENSION_POINT).getExtensions();
    	if (extensions != null)
    		for (int i = 0; i < extensions.length; i++) {
    			String ns = extensions[i].getNamespace();

    			IConfigurationElement[] confs = extensions[i].getConfigurationElements();
    			for (int j = 0; j < confs.length ; j++) {
    				IConfigurationElement conf = confs[j];
    				if (conf.getName().equals(ID_ACTOR_NAME)) {
    					knownActorsConfiguration.add(new ActorDescriptor(conf,ns));
    					    				    					
    				}	
    			}
    		}			
		
	}
	
	/* (non-Javadoc)
	 * @see it.battlehorse.rcp.tools.actors.IActorRegistry#getKnownActorConfiguration()
	 */
	public List<ActorDescriptor> getKnownActorConfiguration() {
		return Collections.unmodifiableList(knownActorsConfiguration);
	}
	
	/* (non-Javadoc)
	 * @see it.battlehorse.rcp.tools.actors.IActorRegistry#getKnownActorConfiguration(boolean)
	 */
	public List<ActorDescriptor> getKnownActorConfiguration(boolean limitOnlyVisibles) {
		if (!limitOnlyVisibles)
			return getKnownActorConfiguration();
		else {
			List<ActorDescriptor> visibleActors = new ArrayList<ActorDescriptor>();
			for (ActorDescriptor conf : knownActorsConfiguration) {
				if (conf.isVisible())					
					visibleActors.add(conf);
			}
			
			return Collections.unmodifiableList(visibleActors);
		}
		
	}

	/*
	 * (non-Javadoc)
	 * @see it.battlehorse.rcp.tools.actors.IActorRegistry#getActorClassForActorId(java.lang.String)
	 */
	public IActor getActorClassForActorId(String actorId) throws CoreException {
		IActor actor = null;
		
		for (ActorDescriptor desc : knownActorsConfiguration) {
			if (desc.getId().equals(actorId))
				actor = desc.getActorInstance();
		}
		
		return actor;
	}
	
	/* (non-Javadoc)
	 * @see it.battlehorse.rcp.tools.actors.IActorRegistry#getActorForView(java.lang.String)
	 */
	public ActorDescriptor getActorForView(String viewId) {
		for (ActorDescriptor element : knownActorsConfiguration) {
			if (element.getViewId().equals(viewId))
				return element;
		}
		
		return null;
	}
	
	/* (non-Javadoc)
	 * @see it.battlehorse.rcp.tools.actors.IActorRegistry#getActorForActorId(java.lang.String)
	 */
	public ActorDescriptor getActorForActorId(String actorId) {
		for (ActorDescriptor element : knownActorsConfiguration) {
			if (element.getId().equals(actorId))
				return element;
		}
		
		return null;		
	}	
	
}
